package com.ibs.hadoop.spring.mybatis.comm;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;

public class BaseDAOImpl implements BaseDAO {

	@Autowired
	private SqlSession sqlSession;

	public int delete(String statementName, Object parameterObject) throws DataAccessException {
		return sqlSession.delete(statementName, parameterObject);
	}

	public int insert(String statementName, Object parameterObject) throws DataAccessException {
		return sqlSession.insert(statementName, parameterObject);
	}

	public <T> List<T> selectList(String statementName, Object parameterObject) throws DataAccessException {
		return sqlSession.selectList(statementName, parameterObject);
	}

	public <T> Pagination<T> selectList(String statementName, int pageNum, int pageSize, Object parameterObject)
			throws DataAccessException {
		int start = (pageNum - 1) * pageSize;
		int limit = pageSize;
		return selectRange(statementName, start, limit, parameterObject);
	}

	public <T> Pagination<T> selectPagination(String statementName, int pageNum, int pageSize, Object parameterObject)
			throws DataAccessException {
		Pagination<T> pagination = new Pagination<T>(pageNum, pageSize);
		Long count = selectOne(statementName + "Count", parameterObject);
		pagination.setTotal(count);
		List<T> pageList = new ArrayList<T>();
		if (count > 0) {
			pageList = sqlSession.selectList(statementName, parameterObject,
					new RowBounds((pageNum - 1) * pageSize, pageSize));
		}
		pagination.setList(pageList);
		return pagination;
	}

	public <T> Pagination<T> selectRange(String statementName, int start, int limit, Object parameterObject)
			throws DataAccessException {
		Pagination<T> pagination = new Pagination<T>(start, limit);
		Long count = 0L;
		if (parameterObject instanceof Map && ((Map) parameterObject).containsKey("pagingTotal")) {
			if (((Map) parameterObject).get("pagingTotal") != null) {
				count = ((Integer) ((Map) parameterObject).get("pagingTotal")).longValue();
			}
		}
		if (count == 0) {
			// count = selectOne(statementName + "Count", parameterObject);
			count = pagination.getTotal();
		}
		pagination.setTotal(count);
		List<T> pageList = sqlSession.selectList(statementName, parameterObject, new RowBounds(start, limit));
		pagination.setList(pageList);
		return pagination;
	}

	public <T> T selectOne(String statementName, Object parameterObject) throws DataAccessException {
		return (T) this.sqlSession.selectOne(statementName, parameterObject);
	}

	public int update(String statementName, Object parameterObject) throws DataAccessException {
		return this.sqlSession.update(statementName, parameterObject);
	}

	public void updateBatch(String statementName, Collection<?> c) throws DataAccessException {
		Iterator<?> it = c.iterator();
		while (it.hasNext()) {
			this.sqlSession.update(statementName, it.next());
		}
	}

	public void insertBatch(String statementName, Collection<?> c) throws DataAccessException {
		Iterator<?> it = c.iterator();
		while (it.hasNext()) {
			this.sqlSession.insert(statementName, it.next());
		}
	}

}
